
#ifndef __UART_PKG_H
#define __UART_PKG_H

#include <stdint.h>
#include <string.h>

#define     UART_PKG_HEAD_TIAL_LEN  (5)     // 串口接收数据包头包尾的最大长度
#define     UART_REC_DATA_SIZE      (128+1) // 串口接收数据的最大长度
#define     UART_TIMEOUT            (10)    // 串口接收超时时间(ms)

/* 串口发送数据结构体 */
typedef struct {
    uint8_t  send_head[5];      // 发送的包头
    uint8_t  send_head_len;     // 发送的包头长度
    uint8_t  send_tail[5];      // 发送的包尾
    uint8_t  send_tail_len;     // 发送的包尾长度
    uint32_t checksum;          // 数据校验和
    
    void (*send_byte)(uint8_t); // 发送字节函数
} uart_send_t;

/* 串口按指定长度接收数据结构体 */
typedef struct {
    uint8_t rec_flag;                       // 串口接收完成标志位
    uint8_t rec_data[UART_REC_DATA_SIZE];   // 串口接收的数据
    uint8_t rec_data_len;                   // 串口接收的数据的实际长度
    uint8_t rec_len;                        // 接收数据长度(1~UART_REC_DATA_SIZE)
    uint8_t rec_cnt;                        // 接收数据计次
    uint8_t rec_start;                      // 串口接收开始
} uart_data_t;

/* 串口字节数组接收结构体(使用包头包尾置接收标志位) */
typedef struct {
    uint8_t rec_state;                              // 接收状态机
    
    uint8_t rec_head[UART_PKG_HEAD_TIAL_LEN];       // 接收的包头数组
    uint8_t rec_head_buf[UART_PKG_HEAD_TIAL_LEN];   // 接收的包头数组缓存
    uint8_t rec_head_cnt;                           // 包头接收计次
    uint8_t rec_head_len;                           // 接收的包头长度(1~5)
    
    uint8_t rec_tail[UART_PKG_HEAD_TIAL_LEN];       // 接收的包尾数组
    uint8_t rec_tail_buf[UART_PKG_HEAD_TIAL_LEN];   // 接收的包尾数组缓存
    uint8_t rec_tail_cnt;                           // 包尾接收计次
    uint8_t rec_tail_len;                           // 接收的包尾长度(1~5)
    
    uint8_t rec_flag;                               // 串口接收完成标志位
    uint8_t rec_arr[UART_REC_DATA_SIZE];            // 串口接收的字节数组
    uint8_t rec_arr_len;                            // 串口接收的字节数组的实际长度
    uint8_t rec_cnt;                                // 串口接收计次
    uint8_t rec_start;                              // 串口接收开始
    uint8_t rec_tmr;                                // 串口接收计时
} uart_arr_t;

/* 串口字符串接收结构体 */
typedef struct {
    uint8_t rec_flag;                   // 串口接收完成标志位
    char rec_str[UART_REC_DATA_SIZE];   // 串口的接收字符串
    uint8_t rec_str_len;                // 串口的接收字符串的实际长度
    uint8_t rec_cnt;                    // 串口接收计次
    uint8_t rec_start;                  // 串口接收开始
    uint8_t rec_tmr;                    // 串口接收计时
} uart_str_t;

/* 发送数据 */
void    uart_send_byte                  (uart_send_t *uartx, uint8_t byte);
void    uart_send_array                 (uart_send_t *uartx, uint8_t *arr, uint8_t len, uint8_t check);
void    uart_send_string                (uart_send_t *uartx, char *str);

/* 接收数据 */
void    uart_data_receive               (uart_data_t *uartx, uint8_t data);
void    uart_data_rec_clearflag         (uart_data_t *uartx);

/* 接收字节数组 */
void    uart_arr_receive                (uart_arr_t *uartx, uint8_t data);
void    uart_arr_rec_timeout_judge      (uart_arr_t *uartx);
void    uart_arr_rec_clearflag          (uart_arr_t *uartx);

/* 接收字符串(使用回车换行符置接收标志位) */
void    uart_str_ln_receive             (uart_str_t *uartx, uint8_t data);
void    uart_str_ln_rec_timeout_judge   (uart_str_t *uartx);
void    uart_str_ln_rec_clearflag       (uart_str_t *uartx);

/* 接收字符串(使用超时检测置接收标志位) */
void    uart_str_receive                (uart_str_t *uartx, uint8_t data);
void    uart_str_rec_timeout_judge      (uart_str_t *uartx);
void    uart_str_rec_clearflag          (uart_str_t *uartx);

/*
串口发送数据结构体定义示例
uart_send_t usx = {
    .send_head = {0x48},            // 指定包头为0x48(字符'H')
    .send_head_len = 1,             // 包头长为1
    .send_tail = {0x54},            // 指定包尾为0x54(字符'T')
    .send_tail_len = 1,             // 包尾长为1
    .send_byte = USART1_SendByte,   // 指定对应的串口发送字节函数
};

串口接收指定长度数据结构体定义示例
uart_data_t urx = {
    .rec_len = 10,  // 指定接收10个数据
};

串口字节数组接收结构体定义示例
uart_arr_t urx = {
    .rec_head = {0xA5},         // 指定包头为0xA5
    .rec_head_len = 1,          // 包头长为1
    .rec_tail = {0x5A, 0x6A},   // 指定包尾为0x5A 0x6A
    .rec_tail_len = 2,          // 包尾长为2
};
*/

#endif
